
    var keyPrefix = 'FlickrPhotoActionsOnThreadPages.';

    GM_log = function (message) {
        console.info("FPA: " + message);
    }

    GM_getValue = function(key, defValue) {
        var retval = window.localStorage.getItem(keyPrefix + key);
        if (!$chk(retval)) {
            return defValue;
        }
        return retval;
    }

    GM_setValue = function(key, value) {
        try {
            window.localStorage.setItem(keyPrefix + key, value);
        } catch (e) {
            GM_log("error setting value: " + e);
        }
    }

    GM_deleteValue = function(key) {
        try {
            window.localStorage.removeItem(keyPrefix + key);
        } catch (e) {
            GM_log("error removing value: " + e);
        }
    }

    GM_listValuesWithMatch = function(match) {
        var list = [];
        var reKey = new RegExp("^" + keyPrefix);
        for (var i = 0, il = window.localStorage.length; i < il; i++) {
            // only use the script's own keys
            var key = window.localStorage.key(i);
            if (key.match(reKey)) {
		var shortKey = key.replace(reKey, '');
	    	if ($chk(match)) {
			if (!shortKey.match(match)) {
				continue; // skip
			}
		}
                list.push(shortKey);
            }
        }
        return list;
    }

    GM_getObject = function (key) {
        var value = GM_getValue(key);
        if ($chk(value)) {
            return JSON.parse(value);
        }
        return null;
    }

    GM_storeObject = function (key, value) {
        GM_setValue(key, JSON.stringify(value));
    }

    var getJSVariable = function (regex) {
        // Thanks to Vispillo for this compact code
        var retval;
        $$('script').each( function (script) {
            if (retval != undefined) {
                return;
            }
            var html = script.innerHTML;
            try {
                retval = html.match(regex)[1];
            } catch (e) {
            }
        });
        return retval;
    }

    GM_getMagisterLudi = function () {
        var reMatch = /global_magisterLudi[ =]+\'([^\']+)\'/;
        var retval = getJSVariable(reMatch);
        if (!$chk(retval)) { // new layout?
            reMatch = /\"?api_key\"?[ :]+[\'\"]([^\'\"]+)[\'\"]/;
	    retval = getJSVariable(reMatch);
        }

        return retval;
    }

    GM_getPhotostreamOwnerNsid = function () {
        var reMatch = /photostream_owner_nsid[ =]+\"([^\"]+)\"/;
        var retval = getJSVariable(reMatch);
	if (!$chk(retval)) {
	    reMatch = /\"owner_nsid\"[ :]+\"([^\"]+)\"/;
	    retval = getJSVariable(reMatch);
	}
	return retval;
    }

    GM_getUserNsid = function () {
        var reMatch = /global_nsid[ =]+\'([^\']+)\'/;
        var retval = getJSVariable(reMatch);
	if (!$chk(retval)) {
	    reMatch = /\"nsid\"[ :]+\"([^\"]+)\"/;
	    retval = getJSVariable(reMatch);
	}
	return retval;
    }

    GM_getGroupId = function () {
    	var reMatch = /\"id\"[ :]+[\'\"]([^\'\"]+@\w\d{2})[\'\"]/;
	var groupId = getJSVariable(reMatch);
	if (!$chk(groupId)) {
		var rssFeeds = $$('a[href*=groups_discuss.gne]');
		if (rssFeeds.length > 0) {
			var groupFeed = rssFeeds[0];
			try {
				groupId = groupFeed.get('href').match(/(\d+@\w\d{2})/)[1];
			} catch (e) {
			// ignore
			}
		}
	}
	return groupId;
    }

    GM_getAuthHash = function () {
        var reMatch = /global_auth_hash[ =]+\'([^\']+)\'/;
        var retval = getJSVariable(reMatch);
        if (!$chk(retval)) { // new layout?
            reMatch = /\"?auth_hash\"?[ :]+[\'\"]([^\'\"]+)[\'\"]/;
	    retval = getJSVariable(reMatch);
        }

        return retval;
    }

    GM_getAuthToken = function () {
        var reMatch = /global_auth_token[ =]+\'([^\']+)\'/;
        var retval = getJSVariable(reMatch);
        if (!$chk(retval)) { // new layout?
            reMatch = /\"?auth_token\"?[ :]+[\'\"]([^\'\"]+)[\'\"]/;
	    retval = getJSVariable(reMatch);
        }
        return retval;
    }

    GM_getSessionKey = function () {
    	return getJSVariable(/\"api_key\"[ :]+\"([^\"]+)\"/);
    }

    GM_addStyle = function(css) {
            var style = document.createElement('style');
	    style.textContent = css;
	    document.getElementsByTagName('head')[0].appendChild(style);
    }

